package com.android.systemui.statusbar.board;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Point;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Build;
import android.os.PowerManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ListAdapter;
import android.widget.ListView;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.Inet4Address;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import android.util.Log;

import com.android.systemui.SystemUIApplication;

import java.util.StringTokenizer;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileNotFoundException;

/**
 * 设备信息实用类
 */
public class BoardUtil {

    /**
     * 获取手机SDK版本号
     */
    public static int getSystemSDKVersion() {
        int sys_version = -1;
        try {
            sys_version = Build.VERSION.SDK_INT;
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        return sys_version;
    }

    public static int getVersionCode() {
        try {
            PackageManager pm = SystemUIApplication.getInstance().getPackageManager();
            PackageInfo pacInfo = pm.getPackageInfo(SystemUIApplication.getInstance().getPackageName(),
                    PackageManager.GET_CONFIGURATIONS);
            return pacInfo.versionCode;
        } catch (NameNotFoundException e) {
            Log.e("BoardUtil", "getVersionCode fail," + e);
        }
        return -1;
    }

    public static String getSignatures() {
        try {
            PackageManager pm = SystemUIApplication.getInstance().getPackageManager();
            PackageInfo pacInfo = pm.getPackageInfo(SystemUIApplication.getInstance().getPackageName(),
                    PackageManager.GET_SIGNATURES);
            if (pacInfo.signatures != null && pacInfo.signatures[0] != null) {
                return pacInfo.signatures[0].toCharsString();
            }
        } catch (NameNotFoundException e) {
            Log.e("BoardUtil", "getVersionCode fail," + e);
        }
        return "";
    }

    public static String getUnderlineVersionCode() {
        String versionCode = "";
        try {
            PackageManager pm = SystemUIApplication.getInstance().getPackageManager();
            PackageInfo pacInfo = pm.getPackageInfo(SystemUIApplication.getInstance().getPackageName(),
                    PackageManager.GET_CONFIGURATIONS);
            versionCode = pacInfo.versionName + "";
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
        String[] split = versionCode.split("\\.");
        String code = "";
        for (int i = 0; i < split.length; i++) {
            if (i == split.length - 1) {
                code += split[i];
            } else {
                code += split[i] + "_";
            }
        }
        return code;
    }

    public static String getVersionName(Context context) {
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo pinfo = pm.getPackageInfo(context.getPackageName(),
                    PackageManager.GET_CONFIGURATIONS);
            // int versionCode = pinfo.versionCode;
            return pinfo.versionName;
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 安装app
     */
    public static void installApp(Context context, File file) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(Uri.fromFile(file),
                "application/vnd.android.package-archive");
        context.startActivity(intent);
    }

    /**
     * 程序是否在前台运行
     * 是否锁屏
     */
    public static boolean isAppOnForeground(Context context) {
        // Returns a list of application processes that are running on the  device
        ActivityManager activityManager = (ActivityManager) context.getApplicationContext()
                .getSystemService(Context.ACTIVITY_SERVICE);
        String packageName = context.getApplicationContext().getPackageName();

        List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
        if (appProcesses == null) return false;

        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        boolean isScreenOn = pm.isScreenOn();//如果为true，则表示屏幕“亮”了，否则屏幕“暗”了。
        if (isScreenOn) {
            for (RunningAppProcessInfo appProcess : appProcesses) {
                // The name of the process that this object is associated with.
                if (appProcess.processName.equals(packageName)
                        && appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 判断程序的运行在前台还是后台
     *
     * @return 0在后台运行  大于0在前台运行  2表示当前主界面是MainFragmentActivity
     */
    public static int isBackground(Context context) {
        ActivityManager activityManager =
                (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        String packageName = context.getPackageName();
        String bingMapMainActivityClassName = "MainActivity";
        String bingMapMainActivityClassName2 = "ChatMainActivity";
        List<ActivityManager.RunningTaskInfo> tasksInfo = activityManager.getRunningTasks(1);
        if (tasksInfo.size() > 0) {
            ComponentName topComponent = tasksInfo.get(0).topActivity;
            if (packageName.equals(topComponent.getPackageName())) {
                // 当前的APP在前台运行
                if (topComponent.getClassName().equals(bingMapMainActivityClassName)
                        || topComponent.getClassName().equals(bingMapMainActivityClassName2)) {
                    // 当前正在运行的是不是期望的Activity
                    return 2;
                }
                return 1;
            } else {
                // 当前的APP在后台运行
                return 0;
            }
        }
        return 0;
    }

    /**
     * 获取Application meta-data数据
     */
    public static String getAppMetaData(Context context, String node) {
        String from = "";
        try {
            if (context == null) {
                context = SystemUIApplication.getInstance();
            }
            ApplicationInfo appInfo = context.getPackageManager()
                    .getApplicationInfo(context.getPackageName(),
                            PackageManager.GET_META_DATA);
            from = appInfo.metaData.getString(node);// 001取不到要通过下面方式来取
//			if (from == null) {
//				int channelInt = appInfo.metaData.getInt("app_channel");
//				from = String.format("%03d", channelInt);
//			}

        } catch (Exception e) {
            e.printStackTrace();
        }

        return from;
    }

    /**
     * 获取Activity meta-data数据
     */
    public static String getActivityMetaData(Activity context, String node) {
        String value = "";
        try {
            ActivityInfo appInfo = context.getPackageManager().getActivityInfo(
                    context.getComponentName(), PackageManager.GET_META_DATA);
            value = appInfo.metaData.getString(node);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }

    /**
     * 获取屏幕密度比
     */
    public static float getDensity() {
        DisplayMetrics dm = SystemUIApplication.getInstance().getResources().getDisplayMetrics();
        return dm.density;
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(float dpValue) {
        final float scale = SystemUIApplication.getInstance().getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     */
    public static int px2dip(float pxValue) {
        final float scale = SystemUIApplication.getInstance().getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    /**
     * 获取屏幕宽度 px值
     */
    public static int getWidth(Context context) {
        DisplayMetrics dm = context.getResources().getDisplayMetrics();
        return dm.widthPixels;
    }

    /**
     * 获取屏幕宽度 px值
     */
    public static int getHeight(Context context) {
        DisplayMetrics dm = context.getResources().getDisplayMetrics();
        return dm.heightPixels;
    }

    /**
     * 获取屏幕真实宽高
     */
    public static int[] getScreenSize(Window window) {
        Display display = window.getWindowManager().getDefaultDisplay();
        Point point = new Point();
        display.getRealSize(point);
        return new int[]{point.x, point.y};
    }

    /**
     * 获取屏幕宽度dp值
     */
    public static int getWidthDip(Context context) {
        DisplayMetrics dm = new DisplayMetrics();
        dm = context.getResources().getDisplayMetrics();
        int width = dm.widthPixels;
        int Dpi = dm.densityDpi;
        return (160 * width) / Dpi;
    }

    /**
     * 获取屏幕高度dp值
     */
    public static int getHeightDip(Context context) {
        DisplayMetrics dm = new DisplayMetrics();
        dm = context.getResources().getDisplayMetrics();
        int height = dm.heightPixels;
        int Dpi = dm.densityDpi;
        return 2 * (160 * height) / Dpi;
    }

    /**
     * 退出程序方法
     */
    public static void exitApp(Context context) {
        // 清空所有活动Activity
        //SystemUIApplication.getInstance().exit();
        // 跳转到桌面
        Intent startMain = new Intent(Intent.ACTION_MAIN);
        startMain.addCategory(Intent.CATEGORY_HOME);
        startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(startMain);
        android.os.Process.killProcess(android.os.Process.myPid());
        System.exit(0);
    }

    /**
     * 判断网络是否可用
     */
    public static boolean isNetAvailable(Context context) {
        try {
            ConnectivityManager manager = (ConnectivityManager) context
                    .getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
            if (manager == null) return false;

            NetworkInfo networkinfo = manager.getActiveNetworkInfo();
            return !(networkinfo == null || !networkinfo.isAvailable()
                    || !networkinfo.isConnectedOrConnecting());
        } catch (Exception e) {
            Log.e("BoardUtil", "isNetAvailable error !", e);
            return false;
        }
    }

    private static String getWifiMacAddress() {
        try {
            String interfaceName = "wlan0";
            List<NetworkInterface> interfaces = Collections
                    .list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface intf : interfaces) {
                if (!intf.getName().equalsIgnoreCase(interfaceName)) {
                    continue;
                }

                byte[] mac = intf.getHardwareAddress();
                if (mac == null) {
                    return "";
                }

                StringBuilder buf = new StringBuilder();
                for (byte aMac : mac) {
                    buf.append(String.format("%02X:", aMac));
                }
                if (buf.length() > 0) {
                    buf.deleteCharAt(buf.length() - 1);
                }
                return buf.toString();
            }
        } catch (Exception e) {
            Log.e("BoardUtil", "getWifiMacAddress error!", e);
        }
        return "";
    }

    /**
     * 动态设置listView高度
     */
    public static void setListViewHeight(ListView listView) {
        // 获取ListView对应的Adapter
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            return;
        }
        int totalHeight = 0;
        //listAdapter.getCount()返回数据项的数目
        for (int i = 0, len = listAdapter.getCount(); i < len; i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0); // 计算子项View 的宽高
            totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度
        }
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight
                + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        // listView.getDividerHeight()获取子项间分隔符占用的高度
        // params.height最后得到整个ListView完整显示需要的高度
        listView.setLayoutParams(params);
    }

    /**
     * 获取listview的高度
     */
    public static int getListViewHeight(ListView pull) {
        int totalHeight = 0;
        ListAdapter adapter = pull.getAdapter();
        if (adapter == null)
            return totalHeight;
        try {
            for (int i = 0; i < adapter.getCount(); i++) { //listAdapter.getCount()返回数据项的数目
                View listItem = adapter.getView(i, null, pull);
                listItem.measure(0, 0); //计算子项View 的宽高
                totalHeight += listItem.getMeasuredHeight(); //统计所有子项的总高度
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

//        ViewGroup.LayoutParams params = pull.getLayoutParams();
//        params.height = totalHeight + (pull.getDividerHeight() * (pull.getCount() - 1));
//        pull.setLayoutParams(params);

        return totalHeight + (pull.getDividerHeight() * (pull.getCount() - 1));
    }

    public static int checkOp(Context context, int op) {
        final int version = Build.VERSION.SDK_INT;
        //AppOpsManager appOpsManager;
        if (version >= 19) {
            Object object = context.getSystemService(Context.APP_OPS_SERVICE);
            Class c = object.getClass();
            try {
                Class[] cArg = new Class[3];
                cArg[0] = int.class;
                cArg[1] = int.class;
                cArg[2] = String.class;
                Method lMethod = c.getDeclaredMethod("checkOp", cArg);
                return (Integer) lMethod.invoke(object, op, Binder.getCallingUid(),
                        context.getPackageName());
            } catch (NoSuchMethodException | IllegalAccessException
                    | IllegalArgumentException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return -1;
    }

    static String getImsiId(Context context) {
        TelephonyManager TelephonyMgr =
                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        return TelephonyMgr.getSubscriberId();
    }

    public String getDeviceId() {//todo 待修改
        try {
            String deviceModel = Build.MANUFACTURER + Build.MODEL;
            PackageInfo pInfo = SystemUIApplication.getInstance().getPackageManager()
                    .getPackageInfo(SystemUIApplication.getInstance().getPackageName(), 0);
            String appVersion = pInfo.versionName + " (" + pInfo.versionCode + ")";
            String systemVersion = "SDK " + Build.VERSION.SDK_INT;
        } catch (Exception e) {
            String deviceModel = "Android unknown";
            String appVersion = "App version unknown";
            String systemVersion = "SDK " + Build.VERSION.SDK_INT;
        }
        return "";
    }

    /**
     * 获取ip地址
     */
    public static String getHostIP() {
        String hostIp = "";
        try {
            Enumeration nis = NetworkInterface.getNetworkInterfaces();
            InetAddress ia;
            while (nis.hasMoreElements()) {
                NetworkInterface ni = (NetworkInterface) nis.nextElement();
                Enumeration<InetAddress> ias = ni.getInetAddresses();
                while (ias.hasMoreElements()) {
                    ia = ias.nextElement();
                    if (ia instanceof Inet6Address) {
                        continue;// skip ipv6
                    }
                    String ip = ia.getHostAddress();
                    if (!"127.0.0.1".equals(ip)) {
                        hostIp = ia.getHostAddress();
                        break;
                    }
                }
            }
        } catch (SocketException e) {
            Log.e("BoardUtil", "getHostIP fail:" + e);
            e.printStackTrace();
        }
        return hostIp;
    }

    public static InetAddress numericToInetAddress(String addrString) throws UnknownHostException {
        try {
            Class<?> threadClazz = Class.forName("android.net.NetworkUtils");
            Method method = threadClazz.getMethod("numericToInetAddress", String.class);
            return (Inet4Address) method.invoke(null, addrString);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 判断网线是否可用
     */
    public static boolean isWirePluggedIn() {
        final String fileName = "/proc/net/dev";
        File file = new File(fileName);
        if (!file.exists()) {
            Log.e("BoardUtil", "file not exists");
            return false;
        }

        try {
            BufferedReader reader = null;
            reader = new BufferedReader(new FileReader(file));
            String line = null;
            while ((line = reader.readLine()) != null) {
                if (line.contains("eth0:")) {
                    break;
                }
            }

            if (TextUtils.isEmpty(line)) return false;
            if (line.contains("eth0:")) {
                StringTokenizer tokenizer = new StringTokenizer(line);
                tokenizer.nextToken();
                final String ethBytes = tokenizer.nextToken();
                reader.close();
                return Integer.parseInt(ethBytes) > 0;
            }

            reader.close();
            return false;
        } catch (FileNotFoundException e) {
            Log.e("BoardUtil", "FileNotFoundException");
        } catch (IOException e) {
            Log.e("BoardUtil", "IOException: " + e.getLocalizedMessage());
        }
        return false;
    }

    static ExecutorService cachedService = null;
    static ExecutorService singleService = null;

    /**
     * @Description 不固定线程池
     * @author <a href="http://t.cn/RvIApP5">ceychen@foxmail.com</a>
     * @date 2014-8-19 15:46:57
     */
    public static ExecutorService getCachedThreadPool() {
        if (cachedService == null) {
            synchronized (BoardUtil.class) {
                if (cachedService == null)
                    cachedService = Executors.newCachedThreadPool();
            }
        }
        return cachedService;
    }

    /**
     * @Description 单线程池
     * @author <a href="http://t.cn/RvIApP5">ceychen@foxmail.com</a>
     * @date 2014-8-19 15:47:02
     */
    public static ExecutorService getSingleThreadPool() {
        if (singleService == null) {
            synchronized (BoardUtil.class) {
                if (singleService == null)
                    singleService = Executors.newSingleThreadExecutor();
            }
        }
        return singleService;
    }

    public static void isNetworkOnline(final Context context, final NetworkOnlineListener listener) {
        if (listener == null) return;
        getCachedThreadPool().submit(new Runnable() {
            @Override
            public void run() {
                ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
                if (!(networkInfo != null && networkInfo.isConnected())) {
                    listener.onNetworkOnline(false);
                    return;
                }
                try {
                    int retryCount = 3;
                    for (int i = 0; i < retryCount; i++) {
                        int exitValue = ShellUtils
                                .execCommand("ping -c 1 -w 1 114.114.114.114", true, true).result;
                        if (exitValue == 0) {
                            listener.onNetworkOnline(true);
                            return;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    listener.onNetworkOnline(false);
                }
                listener.onNetworkOnline(false);
            }
        });
    }

    public static void isWifiOnline(final Context context, final NetworkOnlineListener listener) {
        if (listener == null) return;
        getCachedThreadPool().submit(new Runnable() {
            @Override
            public void run() {
                try {
                    int retryCount = 3;
                    for (int i = 0; i < retryCount; i++) {
                        int exitValue = ShellUtils
                                .execCommand("ping -I wlan0 -c 1 -w 1 114.114.114.114", true, true).result;
                        if (exitValue == 0) {
                            listener.onNetworkOnline(true);
                            return;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    listener.onNetworkOnline(false);
                }
                listener.onNetworkOnline(false);
            }
        });
    }

    public interface NetworkOnlineListener {
        void onNetworkOnline(boolean online);
    }

    /**
     * 获得当前屏幕亮度的模式
     *
     * @return 1 为自动调节屏幕亮度,0 为手动调节屏幕亮度,-1 获取失败
     */
    public static int getScreenMode(Context context) {
        int mode = -1;
        try {
            mode = Settings.System.getInt(context.getContentResolver(),
                    Settings.System.SCREEN_BRIGHTNESS_MODE);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }
        return mode;
    }

    /**
     * 获得当前屏幕亮度值
     *
     * @return 0--255
     */
    public static int getScreenBrightness(Context context) {
        int screenBrightness = -1;
        try {
            screenBrightness = Settings.System.getInt(context.getContentResolver(),
                    Settings.System.SCREEN_BRIGHTNESS);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }
        return screenBrightness;
    }

    /**
     * 设置当前屏幕亮度的模式
     *
     * @param mode 1 为自动调节屏幕亮度,0 为手动调节屏幕亮度
     */
    public static void setScreenMode(Context context, int mode) {
        try {
            Settings.System.putInt(context.getContentResolver(),
                    Settings.System.SCREEN_BRIGHTNESS_MODE, mode);
            Uri uri = Settings.System
                    .getUriFor("screen_brightness_mode");
            context.getContentResolver().notifyChange(uri, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 保存当前的屏幕亮度值，并使之生效
     *
     * @param paramInt 0-255
     */
    public static void setScreenBrightness(Context context, int paramInt) {
        Settings.System.putInt(context.getContentResolver(),
                Settings.System.SCREEN_BRIGHTNESS, paramInt);
        Uri uri = Settings.System
                .getUriFor("screen_brightness");
        context.getContentResolver().notifyChange(uri, null);
    }

    /**
     * 取消重力感应
     *
     * @param context
     */
    public static void disableAccelerometerRotation(Context context) {
        try {
            Settings.System.putInt(context.getContentResolver(),
                    Settings.System.ACCELEROMETER_ROTATION, 0);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置屏幕方向
     *
     * @param context
     * @param rotation
     */
    public static void setScreenRotation(Context context, int rotation) {
        Log.e("", "888888 111getScreenRotation = " + getScreenRotation(context));
        Log.e("", "888888 222setScreenRotation = " + rotation);
        Settings.System.putInt(context.getContentResolver(),
                Settings.System.USER_ROTATION, rotation);
    }

    /**
     * 获取屏幕方向
     *
     * @param context
     */
    public static int getScreenRotation(Context context) {
        try {
            return Settings.System.getInt(context.getContentResolver(),
                    Settings.System.USER_ROTATION);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
            return 0;
        }
    }

}
